package com.hillky.loadbalancer;

import com.hillky.YrpcBootstrap;
import com.hillky.discovery.Registry;
import com.hillky.exceptions.LoadBalancerException;
import com.hillky.loadbalancer.impl.RoundRobinLoadBalancer;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class AbstractLoadBalancer implements LoadBalancer{

    // 一个服务会匹配一个selector
    private Map<String,Selector> cache=new ConcurrentHashMap<>(8);


    @Override
    public InetSocketAddress selectServerAddress(String serviceName,String group) {

        // 1.优先从cache获取一个选择器
        Selector selector = cache.get(serviceName);

        // 2.如果没有，就需要创建selector
        if(selector==null){

            // 对于这个负载均衡器，内部应该维护一个服务列表作为缓存
            List<InetSocketAddress> serviceList = YrpcBootstrap.getInstance().getConfiguration()
                    .getRegistryConfig().getRegistry().lookup(serviceName,group);
            //提供一些算法负责选取合适的节点
            selector =getSelector(serviceList);

            //将selector放入缓存中
            cache.put(serviceName,selector);
        }

        //获取可用节点
        return selector.getNext();
    }

    @Override
    public synchronized void reLoadBalance(String serviceName,List<InetSocketAddress> serviceList) {
        // 根据新的服务列表生成新的selector
        cache.put(serviceName,getSelector(serviceList));
    }

    /**
     * 由子类进行拓展
     * @param serviceList 服务列表
     * @return 负载均衡算法选择器
     */
    protected abstract Selector getSelector(List<InetSocketAddress> serviceList);


}
